package org.andao.core.base.service;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.andao.core.base.model.RootModel;
import org.andao.core.dao.helper.GenericsUtils;
import org.andao.core.dao.helper.Page;
import org.andao.core.dao.helper.QueryFilter;
import org.andao.core.dao.helper.QueryParameter;
import org.andao.core.dao.hibernate.BaseHibernateSupportDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.support.RequestContext;


/**
 * 基础的业务方法实现.
 * 
 * @author Seewo software - Marco.hu(huzhiguo@cvte.cn)
 * @param <T>
 */
@Transactional
public class BaseServiceImpl<T> extends BaseHibernateSupportDao implements BaseService<T> {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	//使用泛型获取实体类型
	protected Class<T> entityClass;

	protected Class<?> getEntityClass() {
		return entityClass;
	}

	@SuppressWarnings("unchecked")
	public BaseServiceImpl() {
		entityClass = GenericsUtils.getGenericClass(getClass());
		logger.debug("获取泛型实例类型：" + entityClass);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T get(Serializable id) {
		return (T) get(getEntityClass(), id);
	}

	@Override
	@Transactional(readOnly = true)
	public Object get(Class<?> clazz, Serializable id) {
		return exGeneralHibernateDao.get(clazz, id);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T load(Serializable id) {	
		return (T)load(getEntityClass(),id);
	}

	@Override
	@Transactional(readOnly = true)
	public Object load(Class<?> clazz, Serializable id) {
		return exGeneralHibernateDao.load(clazz, id);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T findUnique(String hql, Object... values) {
		return (T) exGeneralHibernateDao.findUnique(hql, values);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T findUniqueByProperty(String propertyName, Object value) {
		return (T) exGeneralHibernateDao.findUniqueByProperty(getEntityClass(), propertyName, value);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly = true)
	public List<T> getAll(boolean includeDeleted) {
		if(includeDeleted){
			return (List<T>) exGeneralHibernateDao.getAll(getEntityClass());
		}
		return (List<T>)exGeneralHibernateDao.findByHql("from "+getEntityClass().getSimpleName()+" where isDeleted = ?", 0);
	}

	@Override
	public void saveOrUpdate(T entity) {
		exGeneralHibernateDao.saveOrUpdate(entity);		
	}

	@Override
	@SuppressWarnings("unchecked")
	public T save(T entity) {	
		return (T) exGeneralHibernateDao.save(entity);
	}

	@Override
	public void update(T entity) {
		exGeneralHibernateDao.update(entity);
	}

	@Override
	@SuppressWarnings("unchecked")
	public T merge(T entity) {
		return (T) exGeneralHibernateDao.merge(entity);
	}

	@Override
	public void persist(T entity) {
		exGeneralHibernateDao.persist(entity);		
	}

	@Override
	public void delete(T entity) {
		exGeneralHibernateDao.delete(entity);
	}

	@Override
	public void delete(Serializable id) {
		exGeneralHibernateDao.delete(getEntityClass(), id);
	}

	@Override
	public void batchDelete(String[] ids) {
		exGeneralHibernateDao.batchDelete(getEntityClass(), ids);		
	}

	@Override
	public void batchDelete(List<T> list) {
		exGeneralHibernateDao.batchDelete(list);
	}

	@Override
	public void truncate(Object entity) {
		exGeneralHibernateDao.truncate(entity);
	}

	@Override
	public void truncateByProperty(Class<?> clazz, String propertyName,String value) {
		exGeneralHibernateDao.truncateByProperty(clazz, propertyName, value);	
	}

	@Override
	public void batchTruncate(Class<?> clazz, String[] ids) {
		exGeneralHibernateDao.batchTruncate(clazz, ids);
	}

	@Override
	public void batchSaveOrUpdate(List<T> list) {
		exGeneralHibernateDao.batchSaveOrUpdate(list);
	}

	@Override
	public void flush() {
		exGeneralHibernateDao.flush();		
	}

	@Override
	public void clearCache(T entity) {
		exGeneralHibernateDao.clearCache(entity);
	}

	@Override
	public void clearAllCache() {
		exGeneralHibernateDao.clearAllCache();
	}

	@Override
	public void reloadLazy(Object proxy) {
		exGeneralHibernateDao.reloadLazy(proxy);		
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> findByHqlQuery(String hql, Object query) {
		return (List<T>)exGeneralHibernateDao.findByHqlQuery(hql, query);		
	}
	
	@Override
	@Transactional(readOnly = true)
	public Page findByHqlQuery(Page objPage,String hql, Object query) {
		return exGeneralHibernateDao.findByHqlQuery(objPage, hql, query);		
	}
	
	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> findByHql(String hql, Object... values) {
		return (List<T>)exGeneralHibernateDao.findByHql(hql, values);		
	}

	@Override
	@Transactional(readOnly = true)
	public List<?> findByHql(Class<?> clazz, String hql, Object... values) {
		return exGeneralHibernateDao.findByHql(hql, values);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> findByHql(String hql, Map<String, Object> values) {		
		return (List<T>)exGeneralHibernateDao.findByHql(hql, values);
	}

	@Override
	@Transactional(readOnly = true)
	public Page findByHql(Page page, String hql, Map<String, Object> values) {
		return exGeneralHibernateDao.findByHql(page, hql, values);
	}
	
	@Override
	@Transactional(readOnly = true)
	public Page findBySql(Page page, String sql, Class<?> targetClazz, Object props) {
		return exGeneralHibernateDao.findBySql(page, sql, targetClazz, props);
	}

	@Override
	@Transactional(readOnly = true)
	public List<?> findEntitysByIds(Class<?> clazz, Collection<String> values) {
		return exGeneralHibernateDao.findEntitysByIds(clazz, values);
	}

	@Override
	@Transactional(readOnly = true)
	public Connection getConn() throws SQLException {
		return SessionFactoryUtils.getDataSource(exGeneralHibernateDao.getSessionFactory()).getConnection();
	}

	@Override
	@Transactional(readOnly=true)
	public Page findByCondition(Page page, Class<? extends RootModel> clazz,QueryParameter parameter) {
		//默认为只查询未删除的
		parameter.getCondition().put("EQ_isDeleted", 0);
		Map<String,QueryFilter> filterMap = QueryFilter.parse(parameter.getCondition());//condition map --> query filter		
		return exGeneralHibernateDao.findByCriteria(clazz, page,QueryFilter.parsebySearchFilter(filterMap) );
	}
	
	
}
